namespace Jim.Web.Core;

/// <summary>
/// SqlSugar 实体仓储
/// </summary>
/// <typeparam name="T"></typeparam>
public class SqlSugarRepository<T> : SimpleClient<T> where T : class, new()
{
    protected ITenant iTenant = null;

    public SqlSugarRepository()
    {
        iTenant = App.GetRequiredService<ISqlSugarClient>().AsTenant();
        base.Context = iTenant.GetConnectionScope(SqlSugarConst.MainConfigId);

        // 若实体贴有多库特性，则返回指定库连接
        if (typeof(T).IsDefined(typeof(TenantAttribute), false))
        {
            base.Context = iTenant.GetConnectionScopeWithAttr<T>();
            return;
        }

        // 若实体贴有日志表特性，则返回日志库连接
        if (typeof(T).IsDefined(typeof(LogTableAttribute), false))
        {
            base.Context = iTenant.IsAnyConnection(SqlSugarConst.LogConfigId)
                ? iTenant.GetConnectionScope(SqlSugarConst.LogConfigId)
                : iTenant.GetConnectionScope(SqlSugarConst.MainConfigId);
            return;
        }

        // 若实体贴有系统表特性，则返回默认库连接
        if (typeof(T).IsDefined(typeof(SysTableAttribute), false))
        {
            base.Context = iTenant.GetConnectionScope(SqlSugarConst.MainConfigId);
            return;
        }

        // 若未贴任何表特性或当前未登录或是默认租户Id，则返回默认库连接
        var tenantId = App.User?.FindFirst(ClaimConst.TenantId)?.Value;
        if (string.IsNullOrWhiteSpace(tenantId) || tenantId == SqlSugarConst.MainConfigId) return;

        // 根据租户Id切换库连接, 为空则返回默认库连接
        var sqlSugarScopeProvider = App.GetRequiredService<SysTenantService>().GetTenantDbConnectionScope(long.Parse(tenantId));
        if (sqlSugarScopeProvider == null) return;

        base.Context = sqlSugarScopeProvider;
    }


    public IReportable<T> Reportable(T data)
    {
        return Context.Reportable<T>(data);
    }
    public IReportable<T> Reportable(List<T> list)
    {
        return Context.Reportable<T>(list);
    }
    public IReportable<T> Reportable(T[] array)
    {
        return Context.Reportable<T>(array);
    }

    public IFastest<T> Fastest()
    {
        return Context.Fastest<T>();
    }

    void ThenMapper(IEnumerable<T> list, Action<T> action)
    {
        Context.ThenMapper(list, action);
    }

    public async Task ThenMapperAsync(IEnumerable<T> list, Func<T, Task> action)
    { 
         await Context.ThenMapperAsync(list, action);
    }


    #region 导航插入
    public InsertNavTaskInit<T, T> InsertNav(T data)
    {
        return Context.InsertNav<T>(data);
    }
    public InsertNavTaskInit<T, T> InsertNav(List<T> datas)
    {
        return Context.InsertNav<T>(datas);
    }
    public InsertNavTaskInit<T, T> InsertNav(T data, InsertNavRootOptions rootOptions)
    {
        return Context.InsertNav<T>(data,rootOptions);
    }
    public InsertNavTaskInit<T, T> InsertNav(List<T> datas, InsertNavRootOptions rootOptions)
    {
        return Context.InsertNav<T>(datas, rootOptions);
    }
    #endregion

    #region 导航删除   
    public DeleteNavTaskInit<T, T> DeleteNav(T data)
    {
        return Context.DeleteNav<T>(data);
    }
    public DeleteNavTaskInit<T, T> DeleteNav(List<T> datas)
    {
        return Context.DeleteNav<T>(datas);
    }
    public DeleteNavTaskInit<T, T> DeleteNav(Expression<Func<T, bool>> whereExpression)
    {
        return Context.DeleteNav<T>(whereExpression);
    }
    public DeleteNavTaskInit<T, T> DeleteNav(T data, DeleteNavRootOptions options)
    {
        return Context.DeleteNav<T>(data, options);
    }
    public DeleteNavTaskInit<T, T> DeleteNav(List<T> datas, DeleteNavRootOptions options)
    {
        return Context.DeleteNav<T>(datas, options);
    }
    public DeleteNavTaskInit<T, T> DeleteNav(Expression<Func<T, bool>> whereExpression, DeleteNavRootOptions options)
    {
        return Context.DeleteNav<T>(whereExpression, options);
    }

    #endregion

    #region 导航更新
    public UpdateNavTaskInit<T, T> UpdateNav(T data)
    {
        return Context.UpdateNav<T>(data);
    }
    public UpdateNavTaskInit<T, T> UpdateNav(List<T> datas)
    {
        return Context.UpdateNav<T>(datas);
    }
    public UpdateNavTaskInit<T, T> UpdateNav(T data, UpdateNavRootOptions rootOptions)
    {
        return Context.UpdateNav<T>(data,rootOptions);
    }
    public UpdateNavTaskInit<T, T> UpdateNav(List<T> datas, UpdateNavRootOptions rootOptions)
    {
        return Context.UpdateNav<T>(datas, rootOptions);
    }

    #endregion
}

